//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "CIISMonitor.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------

__fastcall TCIISMonitor::TCIISMonitor( TCIISDBModule *SetDB,
                                       TUSBCANInterface *SetCAN,
                                       TDebugWin *SetDebugWin,
                                       int SetZoneNo,
                                       String SetCtrl)
{
  DB = SetDB;
  CAN = SetCAN;
  DW = SetDebugWin;
  FZoneNo = SetZoneNo;
  Ctrl = SetCtrl;
  NoOpts.Clear();
	int IntervalNo;
	bool PSOffState;

  DB->TabZones->Locate( "ZoneNo", FZoneNo, NoOpts );
  DB->TabControllers->Locate( "CtrlName", Ctrl, NoOpts );

  ZoneCanAdr = DB->TabZones->FieldByName("ZoneCanAdr")->AsInteger;

  NoIR = DB->TabControllers->FieldByName("NoIR")->AsBoolean;
  IntervalNo = DB->TabZones->FieldByName("ZoneSampInterval")->AsInteger;
  TInterval = DB->TabControllers->FieldByName("SampInterval" + IntToStr( IntervalNo ))->AsInteger * Sec_To_mS;
  if( NoIR ) TInterval = max( TInterval, NoIRMinSampTime );




  DB->TabRecordings->Append();
  DB->TabRecordings->FieldValues["RecNo"] = DB->TabRecordings->RecordCount + 1;
  DB->TabRecordings->FieldValues["RecStart"] = Now();
  DB->TabRecordings->FieldValues["RecType"] = 1;
  DB->TabRecordings->FieldValues["SampInterval"]= TInterval / Sec_To_mS;
  DB->TabRecordings->FieldValues["ZoneNo"] = FZoneNo;
  DB->TabRecordings->Post();
  FRecNo = DB->TabRecordings->FieldByName("RecNo")->AsInteger;

  DB->TabZones->Edit();
  DB->TabZones->FieldValues["RecType"] = 1;
  DB->TabZones->FieldValues["RecNo"] = FRecNo;
  DB->TabZones->Post();


  TWarmUp = 0;

  DB->TabSensors->Filter= "[ZoneNo] = " + IntToStr( ZoneNo );
  DB->TabSensors->Filtered= true;
  if( DB->TabSensors->FindFirst() )
  {
	do
	{
	 DB->TabSensors->Edit();
	 DB->TabSensors->FieldValues["RequestStatus"] = -1;
	 DB->TabSensors->Post();

	 // Handel SensorWarmUp

	 TWarmUp = max( TWarmUp, DB->TabSensors->FieldByName("SensorWarmUp")->AsInteger * Sec_To_mS );
	}
   while( DB->TabSensors->FindNext() == true );
  }
  DB->TabSensors->Filter = "";
  DB->TabSensors->Filtered = false;
  DB->TabSensors->Refresh();

  // Handel SensorWarmUP

	if( TWarmUp > 0 )
  {
	if( TWarmUp < TWarmUpMin ) TWarmUp = TWarmUpMin;
	if(( TWarmUp > 0 ) && ( TInterval - TWarmUp >= TWarmUpEnabled )) WUEnabled = true;
	else WUEnabled = false;
  }
  else
  {
	WUEnabled = false;
  }

  if(( TWarmUp > 0 ) && !WUEnabled ) SensorPowerOn();

	PSOffState = false;
  DB->TabPowerSupply->Filter = "[ZoneNo] = " + IntToStr( ZoneNo );
  DB->TabPowerSupply->Filtered = true;
  if( DB->TabPowerSupply->FindFirst() )
  {
    do
		{
		 if( DB->TabPowerSupply->FieldByName("PSVOutEnabled")->AsBoolean == false ) PSOffState = true;
     DB->TabPowerSupply->Edit();
     DB->TabPowerSupply->FieldValues["RequestStatus"]= -1;
     DB->TabPowerSupply->Post();
    }
   while( DB->TabPowerSupply->FindNext() == true);
  }
  DB->TabPowerSupply->Filter = "";
  DB->TabPowerSupply->Filtered = false;
	DB->TabPowerSupply->Refresh();

	// No NoIR function if any PS is in off state

	if( PSOffState ) NoIR = false;


  T = 0;
  TNextEvent = 0;
  if ( WUEnabled ) MState = MSWarmUp;
  else if ( NoIR ) MState = MSPowerOff;
  else MState = MSSample;



  DB->Log( ClientCom, RecStart, High, "Monitor", FRecNo, 0 );


        //TODO: Add your source code here
}

//---------------------------------------------------------------------------

__fastcall TCIISMonitor::~TCIISMonitor()
{

  if( TWarmUp > 0 ) SensorPowerOff();

  DB->TabRecordings->Locate( "RecNo", FRecNo, NoOpts );
  DB->TabRecordings->Edit();
  DB->TabRecordings->FieldValues["RecStop"] = Now();
  DB->TabRecordings->Post();

  DB->Log( ClientCom, RecStop, High, "Monitor", FRecNo, 0 );

  if( NoIR ) RequestPSOn();

        //TODO: Add your source code here
}

//---------------------------------------------------------------------------


void __fastcall TCIISMonitor::OnTimerEvent()
{

  if( T >= TNextEvent)
	{
    switch (MState)
		{
				case MSWarmUp:
					SensorPowerOn();
					TNextEvent += TWarmUp - NoIRDelay;
					MState = MSPowerOff;
					T += SysClock;
				break;

				case MSPowerOff:
					RequestPSOff();
					TNextEvent += NoIRDelay;
					MState = MSSample;
					T += SysClock;
				break;

				case MSSample:
					RequestSample();
					if( NoIR || WUEnabled )
					{
						TNextEvent += AfterSampleDelay;
						MState = MSAfterSample;
						T += SysClock;
					}
					else
					{
						T = SysClock;
						TNextEvent = TInterval;
					}
				break;

				case MSAfterSample:
					if( NoIR )
					{
						RequestPSOn();
						MState = MSPowerOff;
						TNextEvent = TInterval - AfterSampleDelay - NoIRDelay;
					}
					if( WUEnabled )
					{
						SensorPowerOff();
						MState = MSWarmUp;
						TNextEvent = TInterval - AfterSampleDelay - TWarmUp;
					}
        
					T = SysClock;
				break;
		}
  }
  else T += SysClock;
}

//---------------------------------------------------------------------------

void __fastcall TCIISMonitor::RequestPSOn()
{
CAN->SetDigOut( ZoneCanAdr, 0, true );
CAN->SetPSOutputOn( ZoneCanAdr, true );
}

//---------------------------------------------------------------------------

void __fastcall TCIISMonitor::RequestPSOff()
{
CAN->SetDigOut( ZoneCanAdr, 0, false );
CAN->SetPSOutputOn( ZoneCanAdr, false );
}
//---------------------------------------------------------------------------

void __fastcall TCIISMonitor::RequestSample()
{
  Byte msg[8];
  Cardinal flag;
  int RStatus, NewRStatus;
	bool First;

	First = true;  // NewRStatus Used to give all Sensors and PS same Tag

  DB->TabSensors->Filter = "[ZoneNo] = " + IntToStr(ZoneNo);
  DB->TabSensors->Filtered = true;
  if( DB->TabSensors->FindFirst() )
  {
    do
    {
	  RStatus = DB->TabSensors->FieldByName("RequestStatus")->AsInteger;
	  if( RStatus > 0 )
      {
        #if DebugRecordings == 1
        Debug( " Missing data from Node " + IntToStr(DB->TabSensors->FieldByName("SensorSerialNo")->AsInteger));
        #endif
        RStatus = -RStatus;
      }
			if( First )
			{
				First = false;
				NewRStatus = -RStatus + 1;
				if( NewRStatus > 200 ) NewRStatus = 1;
			}
      DB->TabSensors->Edit();
			DB->TabSensors->FieldValues["RequestStatus"] = NewRStatus;
      DB->TabSensors->Post();
    }
    while( DB->TabSensors->FindNext() == true );
  }
	DB->TabSensors->Filter = "";
  DB->TabSensors->Filtered = false;
  DB->TabSensors->Refresh();

  DB->TabPowerSupply->Filter = "[ZoneNo] = " + IntToStr(ZoneNo);
  DB->TabPowerSupply->Filtered = true;
  if( DB->TabPowerSupply->FindFirst() )
  {
    do
    {
		RStatus = DB->TabPowerSupply->FieldByName("RequestStatus")->AsInteger;
      if( RStatus > 0 )
      {
        #if DebugRecordings == 1
        Debug( " Missing data from Node " + IntToStr(DB->TabPowerSupply->FieldByName("PSSerialNo")->AsInteger));
        #endif
        RStatus = -RStatus;
      }
			if( First )
			{
				First = false;
				NewRStatus = -RStatus + 1;
				if( NewRStatus > 200 ) NewRStatus = 1;
			}
			DB->TabPowerSupply->Edit();
			DB->TabPowerSupply->FieldValues["RequestStatus"] = NewRStatus;
      DB->TabPowerSupply->Post();
		}
    while( DB->TabPowerSupply->FindNext() == true);
  }

  DB->TabPowerSupply->Filter = "";
  DB->TabPowerSupply->Filtered = false;
  DB->TabPowerSupply->Refresh();


  flag = canMSG_STD;
  msg[0] = 14;
  msg[1] = NewRStatus;

  if( CAN->SendMsg( ZoneCanAdr, msg, 2, flag ) == 2 )
    #if DebugRecordings == 1
    Debug( "Request sample " + IntToStr(RStatus) + " on CanAdr " + IntToStr(ZoneCanAdr) )
    #endif
    ;
  else
    #if DebugRecordings == 1
    Debug( "TX ERR while requesting sample " + IntToStr(RStatus) + " on CanAdr " + IntToStr(ZoneCanAdr) )
    #endif
    ;
}


void __fastcall TCIISMonitor::Debug(String Message)
{
  if( DW != NULL ) DW->Log(Message);
}

void __fastcall TCIISMonitor::SetDebugWin(TDebugWin * SetDebugWin)
{
  DW = SetDebugWin;
}

void __fastcall TCIISMonitor::SensorPowerOn()
{
  DB->TabSensors->Filter= "[ZoneNo] = " + IntToStr( ZoneNo );
  DB->TabSensors->Filtered= true;
  if( DB->TabSensors->FindFirst() )
  {
    do
    {
	   if( DB->TabSensors->FieldByName("SensorType")->AsInteger == 15 )
		 CAN->SetDigOut( DB->TabSensors->FieldByName("SensorCanAdr")->AsInteger, 0, true );
    }
   while( DB->TabSensors->FindNext() == true );
  }
  DB->TabSensors->Filter = "";
  DB->TabSensors->Filtered = false;
  DB->TabSensors->Refresh();
}

void __fastcall TCIISMonitor::SensorPowerOff()
{
  DB->TabSensors->Filter= "[ZoneNo] = " + IntToStr( ZoneNo );
  DB->TabSensors->Filtered= true;
  if( DB->TabSensors->FindFirst() )
  {
    do
	{
	   if( DB->TabSensors->FieldByName("SensorType")->AsInteger == 15 )
				 CAN->SetDigOut( DB->TabSensors->FieldByName("SensorCanAdr")->AsInteger, 0, false );
    }
   while( DB->TabSensors->FindNext() == true );
  }
  DB->TabSensors->Filter = "";
  DB->TabSensors->Filtered = false;
  DB->TabSensors->Refresh();
}
